<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;

use Illuminate\Http\Request;

use Illuminate\Support\Facades\Auth;

use Illuminate\Support\Facades\DB;

use SimpleSoftwareIO\QrCode\Generator;

use Yansongda\Pay\Pay;

use Yansongda\Pay\Log;

class PayController extends Controller
{

    protected function aliPayConfig()
    {
        return [
            'app_id' => env('ALI_APP_ID', ''),                      // 应用 APPID
            'ali_public_key' => env('ALI_PUBLIC_KEY', ''),          // 支付宝公钥 // 支付宝公钥
            'private_key' => env('ALI_PRIVATE_KEY', ''),            // 商户的 应用私钥   加密方式： **RSA2**
            'notify_url' => env('APP_URL', '') . '/alipay/notify',    // 支付宝异步通知地址
            'return_url' => env('APP_URL', '') . '/alipay/return',    // 支付成功后同步通知地址

            // 使用公钥证书模式，请配置下面两个参数，同时修改ali_public_key为以.crt结尾的支付宝公钥证书路径，如（./cert/alipayCertPublicKey_RSA2.crt）
            // 'app_cert_public_key' => './cert/appCertPublicKey.crt',  // 应用公钥证书路径
            // 'alipay_root_cert' => './cert/alipayRootCert.crt',       // 支付宝根证书路径
            'log' => [                          // optional
                'file' => storage_path('/logs/alipay.log'),
                'level' => 'info',              // 建议生产环境等级调整为 info，开发环境为 debug
                'type' => 'single',             // optional, 可选 daily.
                'max_file' => 30,               // optional, 当 type 为 daily 时有效，默认 30 天
            ],
            'http' => [ // optional
                'timeout' => 5.0,
                'connect_timeout' => 5.0,
                // 更多配置项请参考 [Guzzle](https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html)
            ],
            //'mode' => 'dev', // optional,设置此参数，将进入沙箱模式
        ];
    }

    protected function wechatConfig()
    {
        return [
            'appid' => env('WECHAT_APPID', ''),             // APP APPID
            'app_id' => env('WECHAT_APP_ID', ''),           // 公众号 APPID
            'miniapp_id' => env('WECHAT_MINIAPP_ID', ''),    // 小程序 APPID
            'mch_id' => env('WECHAT_MCH_ID', ''),
            'key' => env('WECHAT_KEY', ''),
            'notify_url' => env('APP_URL', '') . '/wechat/notify',
            //'cert_client' => './cert/apiclient_cert.pem', // optional，退款等情况时用到
            //'cert_key' => './cert/apiclient_key.pem',// optional，退款等情况时用到
            'log' => [ // optional
                'file' => storage_path('/logs/wechat.log'),
                'level' => 'info', // 建议生产环境等级调整为 info，开发环境为 debug
                'type' => 'single', // optional, 可选 daily.
                'max_file' => 30, // optional, 当 type 为 daily 时有效，默认 30 天
            ],
            'http' => [ // optional
                'timeout' => 5.0,
                'connect_timeout' => 5.0,
                // 更多配置项请参考 [Guzzle](https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html)
            ],
            //'mode' => 'dev', // optional, dev/hk;当为 `hk` 时，为香港 gateway。
        ];
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return view('user.pay.index');
    }

    public function pay(Request $request)
    {
        //验证表单
        $request->validate([
            'money' => ['required', 'numeric', 'min:1', 'max:100000'],
        ]);

        switch ($request->pay_type) {
            case 'alipay':  // 支付宝支付

                //  创建订单
                DB::table('pay_record')
                    ->insert([
                        'username' => Auth::user()->username,
                        'pay_type' => $request->pay_type,               // 充值类型
                        'out_trade_no' => time(),                       // 订单号
                        'total_amount' => $request->money,            // 充值金额
                        'created_at' => date('Y-m-d H:i:s'),    // 创建时间
                        'trade_status' => 0,                            // 状态
                    ]);

                $order = [
                    //'body' => Auth::user()->username,
                    'out_trade_no' => time(),
                    'total_amount' => $request->money,
                    'subject' => env('APP_NAME', '') . '充值，订单号：' . time(),
                ];
                if ($this->ismobile()) {
                    $alipay = Pay::alipay($this->aliPayConfig())->wap($order);
                } else {
                    $alipay = Pay::alipay($this->aliPayConfig())->web($order);
                }

                return $alipay;

                break;
            case 'wechat':    // 微信支付

                //  创建订单
                DB::table('pay_record')
                    ->insert([
                        'username' => Auth::user()->username,
                        'pay_type' => $request->pay_type,               // 充值类型
                        'out_trade_no' => time(),                       // 订单号
                        'total_amount' => $request->money,              // 充值金额
                        'created_at' => date('Y-m-d H:i:s'),    // 创建时间
                        'trade_status' => 0,                            // 状态
                    ]);

                $order = [
                    'out_trade_no' => time(),
                    'total_fee' => $request->money * 100, //金额单位分
                    'body' => env('APP_NAME', '') . '充值，订单号：' . time(),
                    'openid' => '',                 //用户标识
                ];

                if ($this->ismobile()) {
                    $wechatpay = Pay::wechat($this->wechatConfig())->wap($order);
                } else {
                    $wechatpay = Pay::wechat($this->wechatConfig())->scan($order);
                }

                /*
                $wechatpay:{
                    "return_code" => "SUCCESS"
                    "return_msg" => "OK"
                    "appid" => "wxc97ab148f8b5c787"
                    "mch_id" => "1490410042"
                    "nonce_str" => "luWRFUOrG0unL2U2"
                    "sign" => "49AA95404FD8D5361A9A198CAFD4E9AA"
                    "result_code" => "SUCCESS"
                    "prepay_id" => "wx2213195209121178cf2e8fb2ddcc7b0000"
                    "trade_type" => "NATIVE"
                    "code_url" => "weixin://wxpay/bizpayurl?pr=lOTDzso00"
                }
                */

                if ($wechatpay->return_code == 'SUCCESS') {

                    $qrcode = (new Generator)->format('png')->size(200)->generate($wechatpay->code_url);
                    $url = base64_encode($qrcode);

                    return view('user.pay.wechat', [
                        'url' => $url,
                        'total_amount' => $request->money,              // 充值金额
                        'out_trade_no' => time(),
                        'created_at' => date('Y-m-d H:i:s'),
                        'subject' => env('APP_NAME', '') . '充值'
                    ]);
                }
                break;
        }
    }


    // 同步通知
    public function alipayReturn()
    {
        $data = Pay::alipay($this->aliPayConfig())->verify(); // 是的，验签就这么简单！

        if ($data) { // 验证成功
            //支付成功后操作
            return redirect(route('pay.index'));
        } else {
            //支付失败通知.
            exit('支付失败');
        }
    }

    //  异步通知
    public function alipayNotify()
    {
        $alipay = Pay::alipay($this->aliPayConfig());

        try {
            $data = $alipay->verify(); // 是的，验签就这么简单！

            // 请自行对 trade_status 进行判断及其它逻辑进行判断，在支付宝的业务通知中，只有交易通知状态为 TRADE_SUCCESS 或 TRADE_FINISHED 时，支付宝才会认定为买家付款成功。
            // 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号；
            // 2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额）；
            // 3、校验通知中的seller_id（或者seller_email) 是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email）；
            // 4、验证app_id是否为该商户本身。
            // 5、其它业务逻辑情况


            //创建订单
            if ($data->trade_status == 'TRADE_FINISHED' || $data->trade_status == 'TRADE_SUCCESS') {

                // 查询日记
                $pay_record = DB::table('pay_record')
                    ->select('username', 'pay_type', 'out_trade_no', 'trade_no', 'total_amount')
                    ->where('out_trade_no', $data->out_trade_no)
                    ->first();

                // 增加金币
                DB::table('users')
                    ->where('username', $pay_record->username)
                    ->increment('money', $data->total_amount);

                // 改变状态
                DB::table('pay_record')
                    ->where('out_trade_no', $data->out_trade_no)
                    ->update([
                        'trade_no' => $data->trade_no,
                        'trade_status' => 1,                        // 状态
                    ]);

                return $alipay->success();

                Log::debug('Alipay notify', $data->all());
            }
        } catch
        (\Exception $e) {
            // $e->getMessage();
        }

        return $alipay->success();// laravel 框架中请直接 `return $alipay->success()`

    }

    //  微信异步通知
    public function wechatNotify()
    {
        $pay = Pay::wechat($this->wechatConfig());

        try {
            $data = $pay->verify(); // 是的，验签就这么简单！

            if ($data->return_code == 'SUCCESS') {

                // 查询日记
                $pay_record = DB::table('pay_record')
                    ->select('username', 'pay_type', 'out_trade_no', 'trade_no', 'total_amount')
                    ->where('out_trade_no', $data->out_trade_no)
                    ->first();

                // 增加金币
                DB::table('users')
                    ->where('username', $pay_record->username)
                    ->increment('money', $data->total_amount);

                // 改变状态
                DB::table('pay_record')
                    ->where('out_trade_no', $data->out_trade_no)
                    ->update([
                        'trade_no' => $data->transaction_id,        // 微信支付订单号
                        'trade_status' => 1,                        // 状态
                    ]);

                return $pay->success();

                Log::debug('Wechat notify', $data->all());
            }
        } catch (\Exception $e) {
            // $e->getMessage();
        }

        return $pay->success();// laravel 框架中请直接 `return $pay->success()`
    }

    // 微信查询订单状态
    public function wechatReturn(Request $request)
    {
        // 查询日记
        $pay_record = DB::table('pay_record')
            ->select('username', 'pay_type', 'out_trade_no', 'trade_no', 'total_amount', 'trade_status')
            ->where('out_trade_no', $request->out_trade_no)
            ->first();

        if ($pay_record->trade_status == 1) {
            $status = true;
        } else {
            $status = false;
        }
        return response()->json(['success' => 'true', 'result' => ['status' => $status]]);
    }

    // 判断手机端
    public function ismobile()
    {
        // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
        if (isset ($_SERVER['HTTP_X_WAP_PROFILE']))
            return true;

        //此条摘自TPM智能切换模板引擎，适合TPM开发
        if (isset ($_SERVER['HTTP_CLIENT']) && 'PhoneClient' == $_SERVER['HTTP_CLIENT'])
            return true;
        //如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
        if (isset ($_SERVER['HTTP_VIA']))
            //找不到为flase,否则为true
            return stristr($_SERVER['HTTP_VIA'], 'wap') ? true : false;
        //判断手机发送的客户端标志,兼容性有待提高
        if (isset ($_SERVER['HTTP_USER_AGENT'])) {
            $clientkeywords = array(
                'nokia', 'sony', 'ericsson', 'mot', 'samsung', 'htc', 'sgh', 'lg', 'sharp', 'sie-', 'philips', 'panasonic', 'alcatel', 'lenovo', 'iphone', 'ipod', 'blackberry', 'meizu', 'android', 'netfront', 'symbian', 'ucweb', 'windowsce', 'palm', 'operamini', 'operamobi', 'openwave', 'nexusone', 'cldc', 'midp', 'wap', 'mobile'
            );
            //从HTTP_USER_AGENT中查找手机浏览器的关键字
            if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
                return true;
            }
        }
        //协议法，因为有可能不准确，放到最后判断
        if (isset ($_SERVER['HTTP_ACCEPT'])) {
            // 如果只支持wml并且不支持html那一定是移动设备
            // 如果支持wml和html但是wml在html之前则是移动设备
            if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
                return true;
            }
        }
        return false;
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function record()
    {
        //查询用户充值数据
        $pay_record = DB::table('pay_record')
            ->select('username', 'pay_type', 'out_trade_no', 'trade_no', 'total_amount','created_at','trade_status')
            ->where('username', Auth::user()->username)
            ->where(function ($query) {
                $query->orWhere('username', 'like', '%' . @$_GET['search'] . '%');
                $query->orWhere('out_trade_no', 'like', '%' . @$_GET['search'] . '%');
                $query->orWhere('trade_no', 'like', '%' . @$_GET['search'] . '%');
            })
            ->orderBy('id', 'desc')
            ->paginate(17)
            ->withPath('?search=' . @$_GET['search'] . '');

        return view('user.pay.record', ['pay_record' => $pay_record]);
    }

}
